import datetime
import logging
import os.path

import pandas as pd

from config import config, kqConfig
from instructions.enum_types import InstructionType, ActionType
from instructions.import_instruction import ImportInstruction
from instructions.instruction import Instruction
from tools import action_logger, concat_file_reply
from wechat.reply import Reply, ReplyType

logger = logging.getLogger(__name__)


class ReportTodayInstruction(Instruction):
    """
    This class of Instruction is used to handle current date orders for packaging, and generate shunfeng template file
    """

    def __init__(self, chatDBHandler=None, query=None):
        super().__init__(chatDBHandler=chatDBHandler, query=query)
        self.insType = InstructionType.REPORT_TODAY
        self.chatDBHandler = chatDBHandler
        self.prompt = """"""
        self.orderPre: pd.DataFrame = None
        self.todayOrders = None
        self.get_shunfeng_orders_fname()
        logger.info(f"[report] Build report by {self.query}, with filename: {self.filename}")

    @action_logger(ActionType.HANDLER_QUERY)
    async def handle_query(self) -> Reply:
        """
        步骤：
        0. 这个报告指令只能在群里使用。所以要检测是否为群
        1. 把当日订单转换为Dataframe的格式
        2. 使用Import_Instruction的static method获得报告dataframe，进行个性化报告
        3. 把订单的dataframe转成顺丰模板格式保存到gen中，命名格式 金桔王_顺丰打单_2024-12-11.xlsx
        4. 回复格式： 顺丰打单文件;;;REPORT_TEXT
        :return:
        """
        if not self.chatDBHandler.msg.is_group:
            return Reply(ReplyType.TEXT, "这个指令只能在群里使用哦，快去群里找我吧！[害羞]")
        self.todayOrders = await self.chatDBHandler.filter_order_by_date()
        logger.debug(f"[report] Start to build today's report. Found orders: {len(self.todayOrders)}")
        if self.todayOrders:
            await self.build_order_df()
            if self.orderPre.empty:
                return Reply(ReplyType.TEXT,
                             "建立订单格式的时候出了点小问题，问问我爹@慌雨，是不是她的垃圾代码【又】出错了？[旺柴]")
        else:
            return Reply(ReplyType.TEXT, "今日没有订单，怎么会这样？？快去跑单啦！[咒骂]")

        reportDF = ImportInstruction.classify_kumquats_data(self.orderPre)
        isShunfengOK = await self.save_shunfeng_orders()
        if isShunfengOK != 'OK':
            return Reply(ReplyType.TEXT, isShunfengOK)
        reportStr = self.build_order_report_str(reportDF)
        return Reply(ReplyType.FILE, concat_file_reply(self.filename, reportStr))

    @action_logger(ActionType.BUILD_ORDER_REPORT_DF)
    async def build_order_df(self) -> None:
        self.orderPre = pd.DataFrame()
        usernames, userPhones, userAddr, \
            custNames, custPhones, custAddrs, \
            kumquatNames, kumquatFormats, quantities, \
            amounts, notes \
            = [], [], [], [], [], [], [], [], [], [], []

        for order in self.todayOrders:
            usernames.append(order.users.name)
            userPhones.append(order.users.phone)
            userAddr.append(order.users.address)
            custNames.append(order.customers.name)
            custPhones.append(order.customers.phone)
            custAddrs.append(order.customers.address)
            kumquatNames.append(order.kumquats.name)
            kumquatFormats.append(order.kumquats.format)
            quantities.append(order.quantity)
            amounts.append(order.amount)
            notes.append(order.note)
        self.orderPre['users__name'] = usernames
        self.orderPre['users__phone'] = userPhones
        self.orderPre['users__address'] = userAddr
        self.orderPre['customers__name'] = custNames
        self.orderPre['customers__phone'] = custPhones
        self.orderPre['customers__address'] = custAddrs
        self.orderPre['kumquats__name'] = kumquatNames
        self.orderPre['kumquats__format'] = kumquatFormats
        self.orderPre['quantity'] = quantities
        self.orderPre['amount'] = amounts
        self.orderPre['note'] = notes
        logger.debug("[report] Build orders dataframe done.")

    @action_logger(ActionType.SAVE_SHUNFENG_EXCEL)
    async def save_shunfeng_orders(self) -> str:
        # TODO: 没想好是否要检测文件已存在，应该不用吧，覆盖就好

        self.orderPre['kumquats_style'] = self.orderPre['kumquats__name'] + ' ' + self.orderPre['kumquats__format']
        shunfengDF = pd.DataFrame(columns=config.SHUNFENG_HEADERS)
        multipleOrders = []
        reversedMap = {v: k for k, v in config.SHUNFENG_HEADERS_MAPPING.items()}
        for col in reversedMap:
            shunfengDF[col] = self.orderPre[reversedMap.get(col)]
        for _, row in shunfengDF.iterrows():
            quantity = row['托寄物数量']
            if quantity > 1:
                multipleOrders.extend([row] * (int(quantity) - 1))
        shunfengFinalDF = pd.concat([shunfengDF, pd.DataFrame(multipleOrders)], ignore_index=True)
        shunfengFinalDF['托寄物数量'] = [1] * len(shunfengFinalDF)

        if len(shunfengFinalDF) != self.orderPre['quantity'].sum():
            logger.error(f"[report] The size doesn't match, with shunfeng size: {shunfengFinalDF.shape[0]} and "
                         f"current date order size: {self.orderPre.shape[0]}")
            return "生成的顺丰打单文件好像数量对不上额...呼叫我爹@慌雨, 我也不知道原因呢[委屈]"
        shunfengFinalDF.sort_values(by=['收件人']).to_excel(self.filename, index=False)
        return 'OK'

    def build_order_report_str(self, reportDF) -> str:
        """
        简洁汇报装果信息。
        有点不想写了。。要不交给人工智障来说？
        :param reportDF:
        :return:
        """
        reportStr = f"【今日订单汇报】\n 装果啦！装果啦！{kqConfig.KUMQUAT_ORCHARD_MASTER}, 这是今天的订单汇总：\n\n"
        reportStr += "=======***========\n"
        for index, row in reportDF.iterrows():
            reportStr += f"🍊 【{row['金桔名称']}】:【{row['数量']}】箱，其中有{row['不要礼盒']}箱不要礼盒。\n"
        reportStr += f"-*- 今天一共要装{reportDF['数量'].sum()}箱的金桔。-*-\n" \
                     f"大家辛苦啦~给{kqConfig.KUMQUAT_ORCHARD_MASTER}送一朵花🌺🌺🌺\n" \
                     f"另外要交给顺丰的订单我也准备好了，发在群里的这个文件里 -->【{os.path.basename(self.filename)}】"
        return reportStr

    def get_shunfeng_orders_fname(self):
        self.filename = os.path.join(config.GEN_FILE_DIR,
                                     f"金桔王_顺丰打单_{datetime.datetime.now().strftime(config.DEFAULT_DATE_FORMAT)}.xlsx")
